﻿using MB.RuleBase.Common;
using Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Business
{
    public class BPFTSaleorder
    {
        
        /// <summary>
        /// 根据批次号获取app分拣明细--明细暂时去除
        /// </summary>
        /// <param name="BatchNO"></param>
        /// <returns></returns>
        public PFTSaleorderLocationModel getpftSaleOrderList(string BatchNO)
        {
            PFTSaleorderLocationModel result = new PFTSaleorderLocationModel();
            result.BatchNO = BatchNO;
            DataTable dsListOrderNO = DatabaseExcuteByXmlHelper.NewInstance.GetDataSetByXml("PFTSaleOrder", "GetPftOrderNOlstByBatchNo", BatchNO).Tables[0];
            StringObjectModel Data1 = new StringObjectModel() { Key = "OrderList", Value = dsListOrderNO };
            DataTable dsLocationRoadway = DatabaseExcuteByXmlHelper.NewInstance.GetDataSetByXml("PFTSaleOrder", "GetPftLocationRoadwayByBatchNo", BatchNO).Tables[0];
            StringObjectModel Data2 = new StringObjectModel() { Key = "LocationRoad", Value = dsLocationRoadway };
            //DataTable dsOrderItem = DatabaseExcuteByXmlHelper.NewInstance.GetDataSetByXml("PFTSaleOrder", "GetPftOrderItemByBatchNo", BatchNO).Tables[0];
            //StringObjectModel Data3 = new StringObjectModel() { Key = "OrderItem", Value = dsOrderItem };
            //result.Data = new StringObjectModel[] { Data1, Data2, Data3 };
            result.OrderList = dsListOrderNO;
            result.LocationRoad = dsLocationRoadway;
            //result.OrderItem = dsOrderItem;
            return result;
        }

        /// <summary>
        /// 根据批次号和巷道号获取九宫格订单及分拣状态
        /// </summary>
        /// <param name="BatchNO"></param>
        /// <returns></returns>
        public PFTSaleorderLocationModel getpftSaleOrderList(string BatchNO ,string roadway)
        {
            PFTSaleorderLocationModel result = new PFTSaleorderLocationModel();
            result.BatchNO = BatchNO;
            DataTable dsListOrderNO = DatabaseExcuteByXmlHelper.NewInstance.GetDataSetByXml("PFTSaleOrder", "GetPftOrderNOlstByBatchNoAndroadway", BatchNO,roadway).Tables[0];
            result.OrderList = dsListOrderNO;
            return result;
        }


        /// <summary>
        /// 根据批次号和巷道号获取待分拣订单及分拣状态
        /// </summary>
        /// <param name="BatchNO"></param>
        /// <returns></returns>
        public PFTSaleorderLocationModel getSortingPftSaleOrderList(string BatchNO, string roadway)
        {
            PFTSaleorderLocationModel result = new PFTSaleorderLocationModel();
            result.BatchNO = BatchNO;
            DataTable dsListOrderNO = DatabaseExcuteByXmlHelper.NewInstance.GetDataSetByXml("PFTSaleOrder", "GetSortingPftOrderNOlstByBatchNoAndroadway", BatchNO, roadway).Tables[0];
            result.OrderList = dsListOrderNO;
            return result;
        }

        /// <summary>
        ///根据分拣批次号设置订单分拣状态
        /// </summary>
        /// <param name="BatchNO"></param>
        /// <param name="SortingFlag"></param>
        /// <returns></returns>
        public bool SetpftSaleOrderState(string BatchNO, int SortingFlag = 1)
        {
            return SetpftSaleorderstatus(BatchNO, SortingFlag);
        }

        /// <summary>
        /// 绑定分拣批次和手机，同时设置分拣状态为“分拣中”，同时写入分拣人员id和开始分拣时间
        /// </summary>
        /// <param name="BatchNO"></param>
        /// <param name="Phone"></param>
        /// <param name="SortingFlag"></param>
        /// <param name="UserID">分拣人员ID</param>
        /// <returns></returns>
        public bool bindBatchandPhone(string BatchNO, string Phone, int UserID,int SortingFlag)
        {
            return SetpftSaleorderstatusAndPhone(BatchNO, Phone, SortingFlag, UserID);
        }

        /// <summary>
        /// 获取当前批次号和手机号判断分拣状态及能否被绑定
        /// </summary>
        /// <param name="BatchNO"></param>
        /// <param name="Phone"></param>
        /// <returns></returns>
        public int getSortingflagByBatchNO(string BatchNO,string Phone)
        {
            return checkSaleOrderTaskIsRunning(BatchNO, Phone);
        }

        /// <summary>
        /// 设置分拣批次的巷道
        /// </summary>
        /// <param name="BatchNO"></param>
        /// <param name="roadway"></param>
        /// <param name="ErrMsg"></param>
        /// <returns></returns>
        public bool SetpftCurrentRoadway(string BatchNO, string roadway,out string ErrMsg)
        {
            ErrMsg = "";
            int RoadwayState = IsRoadwayHasSortingTask(roadway, BatchNO);
            if (RoadwayState==1)
            {
                ErrMsg = "当前巷道有批次正在分拣中......";
                return false;
            }
            if (RoadwayState == 2)
            {
                ErrMsg = "当前批次处于当前巷道分拣";
                return true;
            }
            else
            {
                return SetpftOrderTaskRoadway(BatchNO, roadway);
            }
        }

        /// <summary>
        /// 点亮电子标签并更新分拣明细状态为已亮灯
        /// </summary>
        /// <param name="batchno"></param>
        /// <param name="roadway"></param>
        /// <param name="orderno"></param>
        /// <param name="seq"></param>
        /// <returns></returns>
        public bool LightupElectronicLabel(string batchno, string roadway, string orderno ,out string errorMsg)
        {
            bool _result = false;
            errorMsg = "";
            try
            {
                List<PFT_ELECLabelQTY> LightList = getElecLabelQty(roadway, orderno);
                if (LightList != null && LightList.Count > 0)
                {
                    List<PFT_LIGHTELECLABELINSTRUCTIONS> list = new List<PFT_LIGHTELECLABELINSTRUCTIONS>();
                    //bool _light = false;
                    //点亮电子标签
                    foreach (var item in LightList)
                    {
                        //_light = BLightElecLabel.DisplayElecLabel(item.IPADDRESS, item.LABELID, item.QTY);//此处点亮标签的命令写入亮灯指令表/队列
                        if (!string.IsNullOrEmpty(item.IPADDRESS) && !string.IsNullOrEmpty(item.LABELID))
                        {
                            list.Add(new PFT_LIGHTELECLABELINSTRUCTIONS() { IPADDRESS = item.IPADDRESS.Trim(), LABELID = item.LABELID, QTY = item.QTY });
                            _result = SetpftSaleorderitemStatus(orderno, 1, item.GOODSID);//更新明细为已亮灯
                        }
                    }
                    if (list != null && list.Count > 0)
                    {
                        WriteLightInstructions(list);//写入亮灯指令
                    }
                    if (!_result)
                        errorMsg = "亮灯失败";
                }
                else
                {
                    _result = false;//无亮灯数据
                    errorMsg = "分拣完，无需亮灯";
                }
                return _result;
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                return false;
            }
        }
        
        /// <summary>
        /// 获取所有标签控制器IP列表
        /// </summary>
        /// <returns></returns>
        //public List<string> getIPaddressListBy()
        //{
        //    return getIPaddressList();
        //}

        /// <summary>
        /// 获取所有标签控制器IP列表和标签ID范围
        /// </summary>
        /// <returns></returns>
        public List<PFT_IPListWithIDrange> getIPaddressListWithIDrange()
        {
            return getIPaddressListWithID();
        }

        /// <summary>
        /// 拍电子标签写入数据库
        /// </summary>
        /// <param name="IPaddress"></param>
        /// <param name="LabelID"></param>
        /// <param name="QTYexce"></param>
        /// <returns></returns>
        public bool PressElecLabelReaction(string IPaddress, string LabelID, int QTYexce,out string errorMsg)
        {
            errorMsg = "";
            bool _result=false;
            var oracle = new MB.RuleBase.BulkCopy.SimulatedOracleHelper();
            var db = MB.Orm.Persistence.DatabaseHelper.CreateDatabase();
            var cn = oracle.CreateOracleConnection(db.ConnectionString);
            System.Data.Common.DbTransaction tran = null;
            try
            {
                cn.Open();
                tran = cn.BeginTransaction();
                _result = PressLabelReaction(tran, IPaddress, LabelID, QTYexce);
                if (_result)
                {
                    _result = _result && ReWriteInventory(tran, IPaddress, LabelID, QTYexce);
                    if (_result)
                    {
                        tran.Commit();
                        if (checkRoadwayIsCccupy(IPaddress, LabelID) <= 0)//当不存在未亮灯或已亮灯明细，释放巷道资源
                        {
                            releaseRoadwayIsCccupy(IPaddress, LabelID);
                        }
                        return true;
                    }
                    else
                    {
                        errorMsg = "扣减库存失败，数据回滚";
                        tran.Rollback(); return false;
                    }
                }
                else
                {
                    errorMsg = "回写实拍数量失败，数据回滚";
                    tran.Rollback(); return false;
                }
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                tran.Rollback();
                return false;
            }
            finally
            {
                if (tran != null) tran.Dispose();
                if (cn != null) cn.Close();
                if (cn != null) cn.Dispose();
            }
        }

        /// <summary>
        /// 获取亮灯指令表的亮灯指令数据
        /// </summary>
        /// <returns></returns>
        public List<PFT_LIGHTELECLABELINSTRUCTIONS> GETLightInstructions()
        {
            return getLightInstructions();
        }

        /// <summary>
        /// 删除亮灯指令表的亮灯指令数据
        /// </summary>
        /// <returns></returns>
        public bool DELETELightInstructions()
        {
            return deleteLightInstructions();
        }

        /// <summary>
        /// 当未分拣商品总数大于0，返回false未分拣完
        /// </summary>
        /// <param name="batchno"></param>
        /// <returns></returns>
        public bool CheckBatchIsFinished(string batchno)
        {
            return !checkBatchIsEnd(batchno);
        }
        public bool DebindBatchPHONE(string batchno)
        {
            return DebindBatchPhone(batchno);
        }
        public bool FinishBatch(string batchno)
        {
            return FinishBatchandDebindPhone(batchno);
        }
        public bool Releaseroadway(string roadway)
        {
            return ReleaseCurrentRoadway(roadway);
        }

        /// <summary>
        /// 批量导入订单
        /// Author:周忆粤
        /// </summary>
        /// <param name="Goodsinventory"></param>
        /// <returns></returns>
        public bool Insertgoodsinventory(List<Pft_goodsinventory> Goodsinventory)
        {

            var result = true;
            var message = string.Empty;
            var oracle = new MB.RuleBase.BulkCopy.SimulatedOracleHelper();
            var db = MB.Orm.Persistence.DatabaseHelper.CreateDatabase();
            var cn = oracle.CreateOracleConnection(db.ConnectionString);
            System.Data.Common.DbTransaction tran = null;
            try
            {
                cn.Open();
                tran = cn.BeginTransaction();

                using (MB.RuleBase.BulkCopy.IDbBulkExecute bulk = MB.RuleBase.BulkCopy.DbBulkExecuteFactory.CreateDbBulkExecute(tran))
                {
                    bulk.WriteToServer("Goodsinventory", "InsertGoodsinventory", Goodsinventory);
                }
                tran.Commit();
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                tran.Rollback();
                result = false;
                message = ex.Message;
            }
            finally
            {
                if (tran != null) tran.Dispose();
                if (cn != null) cn.Close();
                if (cn != null) cn.Dispose();
            }
            return result;


        }


        #region private方法
        /// <summary>
        /// 判断当前巷道是否有正在分拣的批次(0:未使用，1:其他批次分拣中，2:本批次分拣中)
        /// </summary>
        /// <param name="roadway"></param>
        /// <returns></returns>
        private int IsRoadwayHasSortingTask(string roadway, string BatchNO)
        {
            int _result = 0;
            var pftSaleorder = DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<PFT_SaleOrder>("PFTSaleOrder", "checkRoadwayIsOnTask", roadway).FirstOrDefault();
            if (pftSaleorder == null )
            {
                _result = 0;
            }
            else if (!pftSaleorder.BATCHNO.Equals(BatchNO))
            {
                _result = 1;
            }
            else
            {
                _result = 2;
            }

            return _result;
        }

        /// <summary>
        /// 获取所有控制器IP列表
        /// </summary>
        /// <returns></returns>
        private List<string> getIPaddressList()
        {
            List<string> list = DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<string>("PFTSaleOrder", "getIPaddressList");
            return list;
        }

        /// <summary>
        /// 获取所有控制器及其所有ID范围
        /// </summary>
        /// <returns></returns>
        private List<PFT_IPListWithIDrange> getIPaddressListWithID()
        {
            List<PFT_IPListWithIDrange> list = DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<PFT_IPListWithIDrange>("PFTSaleOrder", "getIPaddressListWithIDrange");
            return list;
        }

        /// <summary>
        /// 将分拣批次订单9单设置巷道
        /// </summary>
        /// <param name="BatchNO"></param>
        /// <param name="roadway"></param>
        /// <returns></returns>
        private bool SetpftOrderTaskRoadway(string BatchNO, string roadway)
        {
            bool _result = false;
            _result = DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery("PFTSaleOrder", "SetpftOrderTaskRoadway", roadway, BatchNO) > 0;
            return _result;
        }

        /// <summary>
        /// 获取当前批次号和手机号判断分拣状态及能否被绑定
        /// </summary>
        /// <param name="BatchNO"></param>
        /// <returns></returns>
        private int checkSaleOrderTaskIsRunning(string BatchNO,string Phone)
        {
            DataSet dsPhone = DatabaseExcuteByXmlHelper.NewInstance.GetDataSetByXml("PFTSaleOrder", "checkPhoneIsBindSorting", Phone);//查询当前手机绑定的分拣中的批次号
            if (dsPhone != null && dsPhone.Tables.Count > 0 && dsPhone.Tables[0].Rows.Count>0)
            {
                DataTable dt = dsPhone.Tables[0];
                string batchno = dt.Rows[0]["BATCHNO"].ToString();
                if (batchno.Equals(BatchNO))//当前手机绑定的分拣中的批次，可以显示
                {
                    return 2;
                }
                else
                {
                    return 1;
                }
            }
            else
            {
                DataSet ds = DatabaseExcuteByXmlHelper.NewInstance.GetDataSetByXml("PFTSaleOrder", "checkSaleOrderTaskIsRunning", BatchNO);
                if (ds != null && ds.Tables.Count > 0)
                {
                    DataTable dt = ds.Tables[0];
                    if (dt != null && dt.Rows.Count > 0)
                    {
                        string phone = dt.Rows[0]["PHONE"].ToString();
                        int Sortingflag = int.Parse(dt.Rows[0]["sortingflag"].ToString());
                        if (Sortingflag == 2)
                        { return 3; }
                        if (Sortingflag == 0 || (Sortingflag == 1 && string.IsNullOrEmpty(phone)))
                        {
                            return 0;
                        }
                        else if (Sortingflag == 1 && phone.Equals(Phone) )
                        {
                            return 2;
                        }
                        else
                        {
                            return 1;
                        }
                    }
                    else
                    {
                        return 1;
                    }
                }
                else
                {
                    return 1;
                }
            }
        }

        /// <summary>
        /// 获取需要点亮的电子标签列表
        /// </summary>
        /// <param name="Roadway"></param>
        /// <param name="OrderNO"></param>
        /// <returns></returns>
        private List<PFT_ELECLabelQTY> getElecLabelQty(string Roadway, string OrderNO)
        {
            List<PFT_ELECLabelQTY> _resultList = new List<PFT_ELECLabelQTY>();
            _resultList = DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<PFT_ELECLabelQTY>("PFTSaleOrder", "GetPftLightInfoByOrderNORoadWay", OrderNO, Roadway);

            return _resultList;
        }

        /// <summary>
        /// 设置批次的分拣状态
        /// </summary>
        /// <param name="BatchNO"></param>
        /// <param name="SortingFlag"></param>
        /// <returns></returns>
        private bool SetpftSaleorderstatus(string BatchNO, int SortingFlag)
        {
            return DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery("PFTSaleOrder", "SetPFTSaleOrderStatusBybatchNO", SortingFlag, BatchNO) > 0;
        }

        /// <summary>
        /// 根据批次号设置订单的手机和分拣状态，同时写入分拣人员id及分拣开始时间
        /// </summary>
        /// <param name="BatchNO"></param>
        /// <param name="Phone"></param>
        /// <param name="SortingFlag"></param>
        /// <returns></returns>
        private bool SetpftSaleorderstatusAndPhone(string BatchNO, string Phone,int SortingFlag,int pft_UserID)
        {
            return DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery("PFTSaleOrder", "SetPFTSaleOrderStatusAndPhoneBybatchNO", SortingFlag, Phone, BatchNO, pft_UserID) > 0;
        }
        
        /// <summary>
        /// 点亮标签后更新明细状态为已亮灯
        /// </summary>
        /// <param name="OrderNO"></param>
        /// <param name="SortingFlag"></param>
        /// <returns></returns>
        private bool SetpftSaleorderitemStatus(string OrderNO, int SortingFlag ,int GoodsID)
        {
            return DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery("PFTSaleOrder", "SetPFTSaleOrderItemStatusByOrderNO", SortingFlag, OrderNO,GoodsID) > 0;
        }

        /// <summary>
        /// 拍灯写入明细表
        /// </summary>
        /// <param name="tran"></param>
        /// <param name="IP"></param>
        /// <param name="ID"></param>
        /// <param name="qtyexce"></param>
        /// <returns></returns>
        private bool PressLabelReaction(DbTransaction tran,string IP, string ID, int qtyexce)
        {
            return DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery(tran,"PFTSaleOrder", "ElecLabelPressReaction", qtyexce, IP, ID) > 0;
        
        }

        /// <summary>
        /// 拍灯后扣减库存
        /// </summary>
        /// <param name="tran"></param>
        /// <param name="IP"></param>
        /// <param name="ID"></param>
        /// <param name="qty"></param>
        /// <returns></returns>
        private bool ReWriteInventory(DbTransaction tran, string IP, string ID, int qty)
        {
            return DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery(tran, "PFTSaleOrder", "ReWriteInventory", qty, IP, ID) > 0;

        }

        /// <summary>
        /// 写入亮灯指令到指令表中
        /// </summary>
        /// <param name="list"></param>
        private void WriteLightInstructions(List<PFT_LIGHTELECLABELINSTRUCTIONS> list)
        {
            using (MB.RuleBase.BulkCopy.IDbBulkExecute bulk = MB.RuleBase.BulkCopy.DbBulkExecuteFactory.CreateDbBulkExecute())
            {
                bulk.WriteToServer("PFTSaleOrder", "Insert_pft_lightElecLabelinstructions", list);
            }

        }

        /// <summary>
        /// 获取所有亮灯指令
        /// </summary>
        /// <returns></returns>
        private List<PFT_LIGHTELECLABELINSTRUCTIONS> getLightInstructions()
        {
            return DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<PFT_LIGHTELECLABELINSTRUCTIONS>("PFTSaleOrder", "getlightElecLabelinstructions");
        }

        /// <summary>
        /// 删除所有亮灯指令
        /// </summary>
        /// <returns></returns>
        private bool deleteLightInstructions()
        {
            return DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery("PFTSaleOrder", "deletelightElecLabelinstructions") > 0;
        }

        /// <summary>
        /// 检查当前巷道还有亮灯或待亮灯明细
        /// </summary>
        /// <param name="IPaddress"></param>
        /// <param name="LabelID"></param>
        /// <returns></returns>
        private int checkRoadwayIsCccupy(string IPaddress, string LabelID)
        {
            try
            {
                return DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<int>("PFTSaleOrder", "checkCurrentRoadwayIsOccupy", IPaddress, LabelID).FirstOrDefault();
            }
            catch (Exception ex)
            {

                MB.Util.TraceEx.Write(ex.Message);
                return 1;//占用状态
            }
        }

        /// <summary>
        /// 释放巷道
        /// </summary>
        /// <param name="IPaddress"></param>
        /// <param name="LabelID"></param>
        /// <returns></returns>
        private bool releaseRoadwayIsCccupy(string IPaddress, string LabelID)
        {
            try
            {
                return DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery("PFTSaleOrder", "releaseCurrentRoadwayOccupy", IPaddress, LabelID) > 0;
            }
            catch (Exception ex)
            {

                MB.Util.TraceEx.Write(ex.Message);
                return false;//释放巷道失败
            }
        }

        /// <summary>
        /// 判断当前批次明细是否存在为分拣完成的商品总数>0
        /// </summary>
        /// <param name="BatchNO"></param>
        /// <returns></returns>
        private bool checkBatchIsEnd(string BatchNO)
        {
            try
            {
                return DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<int>("PFTSaleOrder", "check_IsBatchEnd", BatchNO).FirstOrDefault() > 0;
            }
            catch (Exception ex)
            {

                MB.Util.TraceEx.Write(ex.Message);
                return false;//释放巷道失败
            }
        }

        private bool DebindBatchPhone(string BatchNO)
        {
            try
            {
                return DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery("PFTSaleOrder", "DebindPhone", BatchNO) > 0;
            }
            catch (Exception ex)
            {

                MB.Util.TraceEx.Write(ex.Message);
                return false;//释放手机失败
            }
        }

        private bool FinishBatchandDebindPhone(string BatchNO)
        {
            try
            {
                return DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery("PFTSaleOrder", "End_PftBatchDebindPhone", BatchNO) > 0;
            }
            catch (Exception ex)
            {

                MB.Util.TraceEx.Write(ex.Message);
                return false;//结束批次并释放手机失败
            }
        }

        private bool ReleaseCurrentRoadway(string RoadWay)
        {
            try
            {
                return DatabaseExcuteByXmlHelper.NewInstance.ExecuteNonQuery("PFTSaleOrder", "ReleaseCurrentRoadway", RoadWay) > 0;
            }
            catch (Exception ex)
            {

                MB.Util.TraceEx.Write(ex.Message);
                return false;//释放巷道失败
            }
        }
        #endregion
    }
}
